package com.tianyuan.lims.utils;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.lang3.tuple.Triple;

import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.regex.Pattern;

public class AlgoStringUtils {
    public static final char ChineseSpace = '　';

    /**
     * 字符串是否包含所有要搜索的内容
     *
     * @param cs
     * @param searchCharSequences
     * @return
     */
    public static boolean containsAll(final CharSequence cs, final CharSequence... searchCharSequences) {
        if (StringUtils.isEmpty(cs) || ArrayUtils.isEmpty(searchCharSequences)) {
            return false;
        }
        for (final CharSequence searchCharSequence : searchCharSequences) {
            if (!StringUtils.contains(cs, searchCharSequence)) {
                return false;
            }
        }
        return true;
    }

    public static boolean containsAllIgnoreCase(final CharSequence cs, final CharSequence... searchCharSequences) {
        if (StringUtils.isEmpty(cs) || ArrayUtils.isEmpty(searchCharSequences)) {
            return false;
        }
        for (final CharSequence searchCharSequence : searchCharSequences) {
            if (!StringUtils.containsIgnoreCase(cs, searchCharSequence)) {
                return false;
            }
        }
        return true;
    }

    public static boolean containsAllIgnoreCaseByInputOrder(final CharSequence cs, final CharSequence... searchCharSequences) {
        if (StringUtils.isEmpty(cs) || ArrayUtils.isEmpty(searchCharSequences)) {
            return false;
        }

        int beginIndex = 0;

        for (final CharSequence searchCharSequence : searchCharSequences) {
            if (!StringUtils.containsIgnoreCase(cs, searchCharSequence)) {
                return false;
            }

            int findPos = StringUtils.indexOf(cs, searchCharSequence, beginIndex);

            if (findPos == -1) {
                return false;
            }

            beginIndex = findPos + searchCharSequence.length();
        }
        return true;
    }

    /**
     * 抽取数字 0 - 9
     *
     * @param str
     * @return
     */
    public static String extractNumeric(String str) {
        StringBuilder ret = new StringBuilder();
        for (int i = 0; i < str.length(); i++) {
            char aChar = str.charAt(i);
            if ('0' <= aChar && aChar <= '9') {
                ret.append(aChar);
            }
        }

        return ret.toString();
    }

    /**
     * 抽取字母数字
     *
     * @param str
     * @return
     */
    public static String extractAlphaNumeric(String str) {
        StringBuilder ret = new StringBuilder();
        for (int i = 0; i < str.length(); i++) {
            char aChar = str.charAt(i);
            if ('a' <= aChar && aChar <= 'z' || 'A' <= aChar && aChar <= 'Z' || '0' <= aChar && aChar <= '9') {
                ret.append(aChar);
            }
        }

        return ret.toString();
    }

    /**
     * 抽取第一个数字字符串
     *
     * @param str
     * @return
     */
    public static String extractFirstNumeric(String str) {
        StringBuilder ret = new StringBuilder();
        for (int i = 0; i < str.length(); i++) {
            char aChar = str.charAt(i);
            if ('0' <= aChar && aChar <= '9') {
                ret.append(aChar);
            } else {
                if (ret.length() > 0) {
                    break;
                }
            }
        }

        return ret.toString();
    }

    /**
     * 从结束开始查找数字字符串
     *
     * @param str
     * @param requireStartIs   要求数字开始就是
     * @param stopSearchOnChar
     * @return null
     */
    public static String extractLastNumeric(String str, boolean requireStartIs, Character stopSearchOnChar) {
        StringBuilder ret = new StringBuilder();
        for (int i = str.length() - 1; i >= 0; i--) {
            char aChar = str.charAt(i);
            if ('0' <= aChar && aChar <= '9') {
                ret.append(aChar);
            } else {
                if (ret.length() > 0 || (null != stopSearchOnChar && stopSearchOnChar.equals(aChar)) || requireStartIs) {
                    break;
                }
            }
        }

        return ret.reverse().toString();
    }

    /**
     * 将字符串 it 按照 like的长度补齐 如果 it的长度小于like
     *
     * @param it
     * @param like
     * @return
     */
    public static String makeUpLengthLikeIfLess(String it, String like) {
        int likeSize = StringUtils.length(like);
        int itSize = StringUtils.length(it);
        if (likeSize <= itSize) {
            return it;
        }

        int size = (likeSize - itSize) / 2;

        StringBuilder builder = new StringBuilder(likeSize + 1);
        builder.append(StringUtils.substring(like, 0, size));
        builder.append(it);
        builder.append(StringUtils.substring(like, size + itSize));
        return builder.toString();
    }

    private static int getStringPrintSize(String str) {
        return str.length()+countTakeSeatCharCountChinese2(str);
//        int size = 0;
//        for (int i = 0; i < str.length(); i++) {
//            if (str.charAt(i) > 255) {
//                size += 2;
//            } else {
//                size++;
//            }
//        }
//        return size;
    }

    /**
     *
     * @param str
     * @param printLength
     * @param left true 左侧补空格 false 右侧补空格
     * @return
     */
    public static String makeUpStringPrintLength(String str, int printLength, boolean left) {
        int printSize = getStringPrintSize(str);
        if (printSize >= printLength) {
            return str;
        } else {
            char[] mu = new char[printLength - printSize];
            for (int i = 0; i < mu.length; i++) {
                mu[i] = ' ';
            }
            String markup = new String(mu);
            if (left) {
                return markup + str;
            } else {
                return str + markup;
            }
        }
    }

    /**
     * join String 删除空串
     *
     * @param separator
     * @param strs
     * @return
     */
    public static <T> String joinStringRemoveEmpty(String separator, Collection<T> strs) {
        return joinStringRemoveEmpty(separator, strs, t -> t == null ? "" : t.toString());
    }

    public static <T> String joinStringRemoveEmpty(String separator, Collection<T> strs, Function<T, String> toStr) {
        if(null == strs){
            return "";
        }

        StringJoiner stringJoiner = new StringJoiner(separator);
        for (T str : strs) {
            if (null == str) {
                continue;
            }
            String _str = toStr.apply(str);
            if (null == str || StringUtils.isEmpty(_str)) {
                continue;
            }
            stringJoiner.add(_str);
        }
        return stringJoiner.toString();
    }

    public static String joinStringRemoveEmpty(String separator, String... strs) {
        return joinStringRemoveEmpty(separator, Arrays.asList(strs));
    }

    public static <T> String joinString(String separator, boolean removeEmpty, boolean removeBlank, boolean removeDuplicate, Collection<T> strs, Function<T, String> toStr) {
        if(null == strs || strs.size() == 0){
            return "";
        }

        List<String> list = null;
        Set<String> noDuplicateEmpty = null;
        if(removeDuplicate){
            noDuplicateEmpty = new LinkedHashSet<>();
        }else{
            list = new Vector<>();
        }

        for (T str : strs) {
            String s = toStr.apply(str);
            if( removeEmpty && StringUtils.isEmpty(s) ){
                continue;
            }
            if( removeBlank && AlgoStringUtils.isBlank(s) ){
                continue;
            }
            if(null==s){
                s = "null";
            }
            if (removeDuplicate) {
                noDuplicateEmpty.add(s);
            }else{
                list.add(s);
            }
        }

        if(removeDuplicate){
            StringJoiner stringJoiner = new StringJoiner(separator);
            noDuplicateEmpty.forEach(s -> stringJoiner.add(s));
            return stringJoiner.toString();
        }else{
            StringJoiner stringJoiner = new StringJoiner(separator);
            list.forEach(s -> stringJoiner.add(s));
            return stringJoiner.toString();
        }
    }

    public static <T> String joinStringStrict(String separtor, Collection<T> strs, Function<T, String> toStr){
        return joinString(separtor, true, true, true, strs, toStr);
    }




    public static List<Integer> splitToIntegerList(String str) {
        return splitToIntegerList(str, ",", true);
    }

    public static List<Integer> splitToIntegerList(String str, String separator) {
        return splitToIntegerList(str, separator, true);
    }

    public static List<Integer> splitToIntegerList(String str, String separator, boolean removeInvalid) {
        if (StringUtils.isBlank(str)) {
            return new Vector<>();
        }

        String[] strings = StringUtils.split(str, separator);
        if (null == strings) {
            return new Vector<>();
        }

        List<Integer> ret = new Vector<>();
        for (String s : strings) {
            s = StringUtils.trim(s);

            if ( StringUtils.isBlank(s) ) {
                if( !removeInvalid ){
                    ret.add(null);
                }
            }else{
                if(NumberUtils.isCreatable(s)){
                    ret.add(Integer.parseInt(s));
                }else{
                    if( !removeInvalid ){
                        ret.add(null);
                    }
                }
            }
        }
        return ret;
    }

    public static <T> List<T> splitToNumberList(String str, String separator, Function<String, T> predicate) {
        if (StringUtils.isBlank(str)) {
            return new Vector<>();
        }

        String[] strings = StringUtils.split(str, separator);
        if (null == strings) {
            return new Vector<>();
        }

        List<T> ret = new Vector<>();
        for (String s : strings) {
            if (StringUtils.isBlank(s)) {
                continue;
            }

            s = StringUtils.trim(s);

            try {
                ret.add(predicate.apply(s));
            } catch (Exception e) {
                //啥也不干
            }
        }
        return ret;
    }

    /**
     * 删除空白字符 包括中文空格 Removes control characters (char <= 32) from both ends of this String, handling null by returning "".
     *
     * @param str
     * @return
     */
    public static String trimToEmpty(String str) {
        str = StringUtils.trim(str);
        str = StringUtils.removeStart(str, "　");
        str = StringUtils.removeEnd(str, "　");

        return StringUtils.defaultString(str);
    }

    public static String trimEnd(String str, String end){
        if( StringUtils.endsWith(str, end) ){
            return StringUtils.substring(str, 0, StringUtils.lastIndexOf(str, end));
        }
        return str;
    }

    /**
     * @param cs
     * @return
     * @See StirngUtils.
     * 检查中文空格
     */
    public static boolean isBlank(final CharSequence cs) {
        int strLen;
        if (cs == null || (strLen = cs.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if (!Character.isWhitespace(cs.charAt(i)) && cs.charAt(i) != '　') {
                return false;
            }
        }
        return true;
    }

    public static boolean isNotBlank(final CharSequence cs) {
        return !isBlank(cs);
    }

    public static boolean isAllBlank(final CharSequence... css) {
        if (ArrayUtils.isEmpty(css)) {
            return true;
        }
        for (final CharSequence cs : css) {
            if (isNotBlank(cs)) {
                return false;
            }
        }
        return true;
    }

    public static boolean isAnyBlank(final CharSequence... css) {
        for (final CharSequence cs : css) {
            if (isBlank(cs)) {
                return true;
            }
        }
        return false;
    }


    /**
     * 检查中文空格
     *
     * @param str
     * @param defaultStr
     * @return
     */
    public static String defaultIfBlank(final String str, final String defaultStr) {
        return isBlank(str) ? defaultStr : str;
    }
    public static String defaultIfBlank(final String str) {
        return isBlank(str) ? "" : str;
    }

    public static List<String> split(final String str, final String separatorChars, boolean removeEmpty, boolean removeBlank) {
        List<String> ret = new Vector<>();

        String[] lines = StringUtils.splitPreserveAllTokens(str, separatorChars);
        if (null != lines) {
            for (String line : lines) {
                boolean add = true;
                if (removeBlank && StringUtils.isBlank(line)) {
                    add = false;
                }

                if (removeEmpty && StringUtils.isEmpty(line)) {
                    add = false;
                }

                if (add) {
                    ret.add(line);
                }
            }
        }
        return ret;
    }

    public static List<String> splitByWholeSeparator(final String str, final String separator, boolean removeEmpty, boolean removeBlank) {
        List<String> ret = new Vector<>();

        String[] lines = StringUtils.splitByWholeSeparator(str, separator);
        if (null != lines) {
            for (String line : lines) {
                boolean add = true;
                if (removeBlank && StringUtils.isBlank(line)) {
                    add = false;
                }

                if (removeEmpty && StringUtils.isEmpty(line)) {
                    add = false;
                }

                if (add) {
                    ret.add(line);
                }
            }
        }
        return ret;
    }

    /**
     * 按行分割 同时删除空白行 trimToEmpty 后
     *
     * @param multiLine
     * @return
     */
    public static List<String> splitByLineRemoveTrimBlank(String multiLine) {
        multiLine = StringUtils.replaceEach(multiLine, new String[]{"\r\n", "\r"}, new String[]{"\n", "\n"});
        List<String> ret = new Vector<>();
        String[] lines = StringUtils.splitPreserveAllTokens(multiLine, "\n");
        if (null != lines) {
            for (String line : lines) {
                if (StringUtils.isNotBlank(trimToEmpty(line))) {
                    ret.add(line);
                }
            }
        }

        return ret;
    }

    /**
     * 按行分割
     *
     * @param multiLine
     * @return
     */
    public static List<String> splitByLine(String multiLine) {
        multiLine = StringUtils.replaceEach(multiLine, new String[]{"\r\n", "\r"}, new String[]{"\n", "\n"});
        List<String> ret = new Vector<>();
        String[] lines = StringUtils.splitPreserveAllTokens(multiLine, "\n");
        if (null != lines) {
            for (String line : lines) {
                ret.add(line);
            }
        }
        return ret;
    }

    public static boolean containsNewline(String str) {
        return StringUtils.containsAny(str, "\r", "\n");
    }

    /**
     * 比较字符串 任意一个为空 false
     *
     * @return
     */
    public static boolean equalsIgnoreCaseFailIfAnyBlank(String a, String b) {
        if (AlgoStringUtils.isBlank(a) || AlgoStringUtils.isBlank(b)) {
            return false;
        }
        return StringUtils.equalsIgnoreCase(a, b);
    }

    /**
     * 字符转成大写
     *
     * @return
     */
    public static char toUpperCase(char c) {
        if (c >= 'A' && c <= 'Z') {
            return c;
        } else if (c >= 'a' && c <= 'z') {
            return (char) (c - 32);
        }
        return c;
    }

    public static char lowerCase(char c) {
        if (c >= 'A' && c <= 'Z') {
            return (char) (c + 32);
        } else if (c >= 'a' && c <= 'z') {
            return c;
        }
        return c;
    }

    public static boolean equalsIgnoreCase(char a, char b) {
        return lowerCase(a) == lowerCase(b);
    }

    public static boolean containsAnyIgnoreCase(final CharSequence cs, final CharSequence... searchCharSequences) {
        for (final CharSequence searchCharSequence : searchCharSequences) {
            if (StringUtils.containsIgnoreCase(cs, searchCharSequence)) {
                return true;
            }
        }

        return false;
    }

    /**
     * 首字母大写
     *
     * @param string
     * @return
     */
    public static String toUpperCaseFirstChar(String string) {
        if (StringUtils.isBlank(string)) {
            return string;
        }

        char[] methodName = string.toCharArray();
        methodName[0] = toUpperCase(methodName[0]);
        return String.valueOf(methodName);
    }

    /**
     * 找到第一个数字开始的字符串。。。
     *
     * @param str
     * @return
     */
    public static String findNumericLeaderString(String str) {
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if ('0' <= c && c <= '9') {
                return StringUtils.substring(str, i);
            }
        }
        return "";
    }

    /**
     * 查找一个字符串是否存在
     *
     * @param str
     * @param finds
     * @return
     */
    public static String findContainAnyIgnoreCase(String str, String... finds) {
        if (null == str) {
            return null;
        }

        for (String find : finds) {
            if (null == find) {
                return null;
            }

            int idx = StringUtils.indexOfIgnoreCase(str, find);
            if (idx != -1) {
                return find;
            }
        }

        return null;
    }

    /**
     * 查找第一个非空blank
     *
     * @param values
     * @param <T>未找到
     * @return
     */
    public static <T extends CharSequence> T firstNonBlank(final T... values) {
        if (values != null) {
            for (final T val : values) {
                if (null == val) {
                    continue;
                }
                if (isNotBlank(val)) {
                    return val;
                }
            }
        }
        return null;
    }

    public static <T extends CharSequence> T firstNonEmpty(final T... values) {
        if (values != null) {
            for (final T val : values) {
                if (null == val) {
                    continue;
                }
                if (StringUtils.isNotEmpty(val)) {
                    return val;
                }
            }
        }
        return null;
    }

    /**
     * 合并连续blank到一个空格 中文空格算空白
     *
     * @return
     */
    public static String margeContinuousBlankToSpace(String str) {
        //合并多个空格到一个空格
        StringBuilder newStr = new StringBuilder(str.length());

        boolean prevIsBlank = false;
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (Character.isWhitespace(c) || c == ChineseSpace) {
                if (prevIsBlank) {
                    continue;
                }
                prevIsBlank = true;
                newStr.append(' ');
            } else {
                prevIsBlank = false;
                newStr.append(c);
            }
        }
        return newStr.toString();
    }

    /**
     * 按连续数字切分字符串
     *
     * @param str
     * @return
     */
    public static List<String> splitByDigits(String str) {
        List<String> chips = new Vector<>();

        StringBuilder chip = null;
        int chipType = -1;

        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);

            int checkChipType = '0' <= c && c <= '9' ? 0 : 1;
            if (-1 == chipType || chipType != checkChipType) {
                if (null != chip && chip.length() > 0) {
                    chips.add(chip.toString());
                }

                chip = new StringBuilder();
                chipType = checkChipType;
            }
            chip.append(c);
        }

        if (null != chip && chip.length() > 0) {
            chips.add(chip.toString());
        }

        return chips;
    }

    private static HashMap<Character, Character> ChCharToEnCharMap = new HashMap<>();static {
        ChCharToEnCharMap.put('—', '-');
        ChCharToEnCharMap.put('：', ':');
        ChCharToEnCharMap.put('　', ' ');
        ChCharToEnCharMap.put('‘', '\'');
        ChCharToEnCharMap.put('（', '(');
        ChCharToEnCharMap.put('）', ')');
    }

    public static boolean equalsIgnoreSymbol(Character char1, Character char2){
        if(null == char1 || null == char2){
            return false;
        }

        if(char1.equals(char2)){
            return true;
        }

        if( ChCharToEnCharMap.containsKey(char1) || ChCharToEnCharMap.containsKey(char2) ){
            char c1 = char1; char c2 = char2;
            if( ChCharToEnCharMap.containsKey(c1) ){
                c1 = ChCharToEnCharMap.get(c1);
            }
            if( ChCharToEnCharMap.containsKey(c2) ){
                c2 = ChCharToEnCharMap.get(c2);
            }
            if(c1 == c2){
                return true;
            }
        }

        return false;
    }

    /**
     * 清理成英文的字符串
     *
     * @param str
     */
    private static String[] cchars = new String[]{"—", "：", "　", "‘", "（", "）"};
    private static String[] echars = new String[]{"-", ":", " ", "'", "(", ")"};

    public static String convertNormalEngString(String str) {
        return StringUtils.replaceEachRepeatedly(str, cchars, echars);
    }

    /**
     * 删除连续空格
     *
     * @param str
     * @return
     */
    public static String removeContinueSpace(String str) {
        if (!StringUtils.containsAny(str, ' ', '　')) {
            return str;
        }

        boolean preSpace = false;
        StringBuilder ret = new StringBuilder(str.length());
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (' ' == c || '　' == c) {
                if (!preSpace) {
                    ret.append(c);
                    preSpace = true;
                }
            } else {
                preSpace = false;
            }
        }

        return ret.toString();
    }

    /**
     * 删除空白字符包括中文空格
     *
     * @param str
     * @return
     */
    public static String removeBlankChar(String str) {
        if (!StringUtils.containsAny(str, ' ', '　')) {
            return str;
        }

        StringBuilder ret = new StringBuilder(str.length());
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (Character.isWhitespace(c) || '　' == c) {

            } else {
                ret.append(c);
            }
        }

        return ret.toString();
    }

    public static String removeStartAny(String str, String... starts) {
        if (StringUtils.isEmpty(str)) {
            return str;
        }

        for (int i = 0; i < starts.length; i++) {
            if (StringUtils.isEmpty(starts[i])) {
                continue;
            }

            if (str.startsWith(starts[i])) {
                return str.substring(starts[i].length());
            }
        }

        return str;
    }


    /**
     * 最终结果转换成小写
     *
     * @param str
     * @return
     */
    public static String getEqualIdentifyString(String str) {
        //删除所有空格
        str = removeBlankChar(str);
        return StringUtils.lowerCase(convertNormalEngString(str));
    }

    public static String getEqualIdentifyString(String str, String noMeanSymbol) {
        //删除所有空格
        str = removeBlankChar(str);
        str = StringUtils.lowerCase(convertNormalEngString(str));

        if( StringUtils.isNotEmpty(noMeanSymbol) ){
            str = removeNoMeanSymbol(str, noMeanSymbol);
        }
        return str;
    }

    public static final String NoMeanSymbols = " 　()（）,，;；‘、。-—_\\/《》.#";

    private static boolean isNoMeanSymbol(Character c) {
        for (int i = 0; i < NoMeanSymbols.length(); i++) {
            if (c == NoMeanSymbols.charAt(i) || Character.isWhitespace(c)) {
                return true;
            }
        }
        return false;
    }

    private static boolean isNoMeanSymbol(String nomeans, Character c) {
        if( null == nomeans || nomeans.isEmpty() ){
            return false;
        }
        return nomeans.indexOf(c)>-1;
    }

    public static String removeNoMeanSymbol(String str) {
        int strLen;
        if (str == null || (strLen = str.length()) == 0) {
            return "";
        }

        StringBuilder result = new StringBuilder();

        for (int i = 0; i < strLen; i++) {
            if (!Character.isWhitespace(str.charAt(i)) && !isNoMeanSymbol(str.charAt(i))) {
                result.append(str.charAt(i));
            }
        }
        return result.toString();
    }

    public static String removeNoMeanSymbol(String str, String nomeans) {
        int strLen;
        if (str == null || (strLen = str.length()) == 0) {
            return "";
        }

        StringBuilder result = new StringBuilder();

        for (int i = 0; i < strLen; i++) {
            if (!Character.isWhitespace(str.charAt(i)) && !isNoMeanSymbol(nomeans, str.charAt(i))) {
                result.append(str.charAt(i));
            }
        }
        return result.toString();
    }

    public static boolean containsStandaloneWord(String str, String word) {
        int beginIndex = StringUtils.indexOf(str, word);
        if (-1 == beginIndex) {
            return false;
        }

        if (beginIndex - 1 >= 0) {
            if (!isNoMeanSymbol(str.charAt(beginIndex - 1))) {
                return false;
            }
        }

        int endIndex = beginIndex + word.length();
        if (endIndex < str.length()) {
            if (!isNoMeanSymbol(str.charAt(endIndex))) {
                return false;
            }
        }

        return true;
    }

    /**
     * 获取首字母
     *
     * @param str
     * @param defaultChar
     * @return
     */
    public static char defaultChar(String str, char defaultChar) {
        if (null == str || str.length() == 0) {
            return defaultChar;
        }
        return str.charAt(0);
    }

    /**
     * 删除左右的开始结束字符
     *
     * @param str
     * @return
     */
    public static String removeStartEndChar(String str, String chars) {
        if (StringUtils.isEmpty(str)) {
            return "";
        }

        int begin = -1;
        int end = str.length();

        for (int i = 0; i < str.length(); i++) {
            boolean isRemoved = false;
            char c = str.charAt(i);
            for (int j = 0; j < chars.length(); j++) {
                if (c == chars.charAt(j)) {
                    isRemoved = true;
                    break;
                }
            }

            if (isRemoved) {
                begin = i;
            } else {
                break;
            }
        }

        for (int i = str.length() - 1; i > begin; i--) {
            boolean isRemoved = false;
            char c = str.charAt(i);
            for (int j = 0; j < chars.length(); j++) {
                if (c == chars.charAt(j)) {
                    isRemoved = true;
                    break;
                }
            }

            if (isRemoved) {
                end = i;
            } else {
                break;
            }
        }

        if (end <= begin) {
            return "";
        }

        return StringUtils.substring(str, begin + 1, end);
    }

    public static String removeChars(String str, char... cs) {
        if (str == null || str.length() == 0) {
            return "";
        }

        StringBuilder result = new StringBuilder(str.length());

        boolean removed;
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            removed = false;
            for (int j = 0; j < cs.length; j++) {
                if (c == cs[j]) {
                    removed = true;
                    break;
                }
            }
            if (!removed) {
                result.append(c);
            }
        }

        return result.toString();
    }



    /**
     * @param str
     * @param prefix
     * @return
     */
    public static StringBuilder appendStringBuilderIfNotBlank(StringBuilder stringBuilder, String str, String prefix) {
        if (isBlank(str)) {
            return stringBuilder;
        }

        if (stringBuilder.length() > 0 && isNotBlank(prefix)) {
            stringBuilder.append(prefix);
        }
        stringBuilder.append(str);

        return stringBuilder;
    }



    public static String ellipsisString(String str, int maxSize) {
        if (StringUtils.isEmpty(str)) {
            return "";
        }
        if (str.length() > maxSize) {
            return StringUtils.substring(str, 0, str.length() - 4) + "...";
        } else {
            return str;
        }
    }

    public static List<String> removeBlank(List<String> strings) {
        List<String> strs = new Vector<>();
        for (String str : CollectionUtils.emptyIfNull(strings)) {
            if (!AlgoStringUtils.isBlank(str)) {
                strs.add(str);
            }
        }
        return strs;
    }

    public static String toASCII(String str) {
        if (StringUtils.isEmpty(str)) {
            return "";
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (0 <= c && c <= 255) {
                stringBuilder.append(c);
            }
        }
        return stringBuilder.toString();
    }


    /**
     * 对齐数字 对齐到个位数
     * @return
     */
    public static List<String> prettyAlignNumber( List<String> nums ){
        List<Triple> numTriples = new Vector<>();
        for ( String num : CollectionUtils.emptyIfNull(nums) ){
            String l = "", m = "", r = "";
            if( StringUtils.contains(num, ".") ){
                m = ".";
                String[] segs = StringUtils.split(num, ".");
                l = segs[0];
                r = segs[1];
            }else{
                l = num;
            }

            Triple<String, String, String> triple = Triple.of(l, m, r);
            numTriples.add(triple);
        }

        int lsize = 0, msize = 0 , rsize = 0;
        for ( Triple<String, String, String> triple : numTriples ){
            lsize = Math.max(lsize, StringUtils.length(triple.getLeft()));
            msize = Math.max(msize, StringUtils.length(triple.getMiddle()));
            rsize = Math.max(rsize, StringUtils.length(triple.getRight()));
        }

        List<String> ret = new Vector<>();
        for ( int i = 0; i < numTriples.size(); i++ ){
            Triple<String, String, String> triple = numTriples.get(i);
            String n = AlgoStringUtils.makeUpStringPrintLength(triple.getLeft(),lsize, true)
                    +  AlgoStringUtils.makeUpStringPrintLength(triple.getMiddle(),msize, false)
                    + AlgoStringUtils.makeUpStringPrintLength(triple.getRight(), rsize, false);
            ret.add( n );
        }

        return ret;
    }

    public static String trimRightNotNumber(String str){

        int endPos = -1;
        for ( int i = str.length()-1; i >= 0 ; i-- ){
            char c = str.charAt(i);
            if( '0' <= c && c <= '9' ){
                endPos = i+1;
                break;
            }
        }
        if(-1==endPos){
            return str;
        }else{
            str = StringUtils.substring(str, 0, endPos);
            return str;
        }
    }

    /**
     * not finish
     * @param str
     * @return
     */
    public static String removeStartNumber(String str){
        if( StringUtils.isEmpty(str) ){
            return str;
        }

        int inNegative = -1;
        int inDecimal = -1;
        int inExponent = -1;
        int inExponentNegative = -1;

        int lastPos = -1;

        for ( int i = 0; i < str.length(); i++ ){
            char c = str.charAt(i);
            if( c == '-' ){
                if( inExponent >= 0 ){
                    if( inExponentNegative >= 0 || (i - inExponent) != 1){
                        break;
                    }else{
                        inExponentNegative = i;
                    }
                }else{
                    if( i != 0 || inNegative >= 0 ){
                        break;
                    }else{
                        //负数开始
                        inNegative = i;
                    }
                }
            }else if( c == '.' ){
                if( inDecimal >= 0 || inExponent >= 0 ){
                    break;
                }else{
                    inDecimal = i;
                }
            }else if( c == 'E' || c == 'e' ){
                if( inExponent >= 0 ){
                    break;
                }else{
                    inExponent = i;
                }
            }else if( '0' <= c && c <= '9' ){

            }else{
                break;
            }

            lastPos = i;
        }

        if( lastPos == -1 ){

        }

        String n = ""; String exponent = "";
        if( inExponent >= 0 ){
            n = StringUtils.substring( str,0, inExponent-1);
            exponent = StringUtils.substring(str, inExponent, lastPos+1);
        }

        //只有符号没有数字
        int nsize = lastPos - (inNegative >= 0 ? 1 : 0) - (inDecimal >= 0 ? 1 : 0) - (inExponent >= 0 ? 1 : 0) - (inExponentNegative >= 0 ? 1 : 0);
        if(nsize == 0){
            return str;
        }

        if( inExponent >= 0 && ((lastPos - inExponent - (inExponentNegative >= 0 ? 1 : 0)) == 0)  ){
            lastPos = inExponent-1;
        }

        //
        return "";
    }

    public static String getCommonEnding(String str1, String str2) {
        if( str1 == null || str2 == null ){
            return "";
        }

        if(str1.length() == 0 || str2.length() == 0){
            return "";
        }

        StringBuilder commonEnding = new StringBuilder();

        // 获取两个字符串的长度
        int len1 = str1.length();
        int len2 = str2.length();

        // 从字符串的末尾开始比较
        int index1 = len1 - 1;
        int index2 = len2 - 1;

        // 向前比较，直到字符不同或到达字符串开头
        while(index1 >= 0 && index2 >= 0 && str1.charAt(index1) == str2.charAt(index2)) {
            commonEnding.append(str1.charAt(index1)); // 或者使用 str2.charAt(index2)，因为此时它们相等
            index1--;
            index2--;
        }

        // 反转StringBuilder以获得正确的结尾字符串顺序
        return commonEnding.reverse().toString();
    }

    public static String addPrefixToLine(String str, String prefix){
        StringBuilder stringBuilder = new StringBuilder();
        List<String> stringList = splitByLine(str);
        for ( int i = 0; i < stringList.size(); i++ ){
            String line = stringList.get(i);
            stringBuilder.append(prefix + line + "\r\n");
        }
        return stringBuilder.toString();
    }

    /**
     * 统计字符个数 中文字符占两个
     *
     * @param text
     * @return
     */
    private static Pattern ChinesePattern = Pattern.compile("^[\u4E00-\u9Fa5]*$");
    public static int countTakeSeatCharCountChinese2(String text) {
        if (StringUtils.isEmpty(text)) {
            return 0;
        }
        int amount = 0;
        for (int i = 0; i < text.length(); i++) {
            boolean matches = ChinesePattern.matcher(text.charAt(i) + "").matches();
            if (matches) {
                amount += 2;
            } else {
                amount += 1;
            }
        }
        return amount;
    }

    public static void addIfNotBlank(Collection<String> strs, String str ) {
        if (StringUtils.isNotBlank(str)) {
            strs.add(str);
        }
    }

    public static void consumeIfNotBlank(String s, Consumer<String> consumer){
        if( AlgoStringUtils.isNotBlank(s) ){
            consumer.accept(s);
        }
    }

    public static void consume(String s, Consumer<String> consumer){
        consumer.accept(s);
    }

    /**
     * 删除开始字符串
     * @param str
     * @param delimiters
     * @return
     */
    public static String[] startSplitIgnoreCaseByAny(String str, String... delimiters) {
        for ( String deliter : delimiters ){
            if( StringUtils.startsWithIgnoreCase(str, deliter) ){
                return new String[]{ deliter, StringUtils.removeStart(str, deliter) };
            }
        }
        return null;
    }
}
